import React, { useEffect } from 'react';
import { Button, Select, Space, Spin } from 'antd';
import { features, useTablePipeline } from 'ali-react-table';
import _ from 'lodash';
import { connect } from 'umi';

import { UploadOutlined } from '#/utils/antdIcons.js';
import { HttpCode } from '#/utils/contacts.js';
import { PageLoading, TRDefault } from '@/components/index.js';
import { TjChart, TjDimension, TjTable, useTRState } from '@/pages/ETrade/components';
import { useExcel } from '@/hooks';

import { default as HeadForm } from './form';
import { queryClearResultBySequence, queryMarketList } from './services.js';
import { CODE1, getColumns, getNXChartOption, getTableData, tradeOptions } from './helper';
import styles from './index.less';
import { getTreeByCodes } from '@/utils';
import { useThemeChange } from '@/hooks';

const orderDefault = ['交易单元', '序列', '时点'];
const orderOptions = ['交易单元', '序列', '日期', '时点'];
const OPTION_KEY = {
  交易单元: 'stationName',
  序列: 'tradeSequenceName',
  日期: 'date',
  时点: 'timeOrder',
};

const RollTradeClearingResults = ({ menuCode, buttonPermissions }) => {
  /** data */
  const [state, setState] = useTRState({
    canExport: buttonPermissions.some((item) => item.menuCode === 'TradingClearResultExportButton'),
    // 初始化三件套
    spinning: true,
    error: '',
    power: [],
    // 表单
    formValues: null,
    order: [...orderDefault], // 聚合维度（bind）
    filters: [], // 详情，已选维度值
    filterOptions: [], // 详情，维度选项
    // 数据
    loading: true,
    chartOptions: null,
    tableColumns: [],
    tableData: [],
    exportTable: [],
    title: '',
    tradeItem: {},
  });
  const { theme } = useThemeChange();

  React.useEffect(() => {
    init();
  }, []);

  /** apis */
  const init = async () => {
    // 权限
    const res = await queryMarketList(menuCode);
    let power = [];
    let error = '';
    if (res?.statusCode === HttpCode.SUCCESS) {
      // tree需要唯一值键，处理一下
      power = getTreeByCodes(['market', 'group', 'station'], res?.json).treeOptions;
    } else {
      error = res?.message || '系统异常';
    }
    setState({
      power,
      error,
      spinning: false,
    });
  };

  const fetch = async () => {
    // 数据
    const { order, formValues } = state;
    if (!formValues) return;
    setState({ loading: true });
    const res = await queryClearResultBySequence({
      flexAggrBody: {
        order: order.map((t) => OPTION_KEY[t]),
        orderSize: order.length,
        needTotal: true,
        timeOrder: '96',
        headType: 1,
      },
      spotResumptionInProvinceBody: {
        ...formValues,
        tag: 1,
        dimension: 'ds',
        pointNum: '96',
      },
      menuCode,
      // order,
      // ...formValues,
    });
    if (!_.isEmpty(res?.data?.data)) {
      const { tableData, exportTable } = getTableData(res?.data, order, formValues.marketId);
      state.tableData = tableData;
      // 聚合维度处理
      const filters = Array.from({ length: order.length - 1 }, () => 0);
      onChangeFilters(filters);
      setState({
        filters,
        tableData,
        exportTable,
      });
    }
    setState({
      loading: false,
    });
  };

  /** methods */
  const onChangeForm = (values, tradeItem) => {
    // 查询
    const formValues = { ...values };
    const chartOptions = _.cloneDeep(tradeItem.chartOptions);
    state.formValues = formValues;
    state.chartOptions =
      formValues.marketId === 'PXBNX'
        ? getNXChartOption(['clearingPrice', 'averageMarketPrice', 'earnings'])
        : chartOptions;
    setState({
      formValues,
      chartOptions,
      tableColumns:
        formValues.marketId === 'PXBNX'
          ? getColumns([
              'tradeRole',
              'clearingQuantity',
              'clearingPrice',
              'averageMarketPrice',
              'earnings',
            ])
          : tradeItem.tableColumns,
      title: tradeItem.value,
      tradeItem,
    });
    fetch();
  };

  const onChangeFilters = (filters) => {
    // 聚合维度处理
    let tableData = state.tableData || [];
    let chartOptions = state.chartOptions;
    let _options = [];
    const len = filters.length;
    const fn = (list, lv) => {
      const dataI = filters[lv];
      const { children = [] } = list[dataI] || {};
      if (lv === len) {
        _options[lv] = list;
      } else {
        _options[lv] = list.map((x, idx) => ({ label: x[CODE1], value: idx }));
      }
      lv < len && fn(children, lv + 1);
    };
    // 去掉总合计
    fn(tableData.slice(1), 0);
    // 拿到选项和渲染结果
    const filterOptions = _options.slice(0, -1);
    const chartData = _options?.[_options.length - 1];
    if (!!chartOptions && !!chartData?.length) {
      chartOptions.dataset.source = chartData;
    }
    setState({
      chartOptions,
      filterOptions,
    });
  };

  const onChangeFilterItem = (lv, idx) => {
    // 当前维度索引更新，子维度索引清0
    let { filters } = state;
    const arrBefore = filters.slice(0, lv + 1);
    const arrAfter = filters.slice(lv + 1).map(() => 0);
    filters = [...arrBefore, ...arrAfter];
    filters[lv] = idx;
    setState({ filters });
    onChangeFilters(filters);
  };

  const _onExport = () => {
    // 导出
    if (!state.canExport) return Message.info('请联系管理员获取相关权限');
    useExcel({
      filename: `${state.title}出清结果`,
      columns: state.tableColumns,
      data: state.exportTable,
    });
  };

  /** render */
  const pipeline = useTablePipeline({ components: {} })
    .input({ dataSource: state.tableData, columns: state.tableColumns })
    .primaryKey('id')
    .use(
      features.treeMode({
        iconIndent: 5,
      }),
    ); // 表格

  // 该逻辑改动过大 待测试
  useEffect(() => {
    if (Object.keys(state.tradeItem).length > 0) {
      setTimeout(() => {
        const list = tradeOptions();
        const index = _.findIndex(list, (n) => n.value === state.tradeItem.value);
        const currentObj = list[index];
        let chartOptions = _.cloneDeep(currentObj.chartOptions);

        if (state.formValues.marketId === 'PXBNX') {
          chartOptions = getNXChartOption(['clearingPrice', 'averageMarketPrice', 'earnings']);
        }

        chartOptions.dataset.source = state.chartOptions.dataset.source;

        setState({
          chartOptions,
        });
      }, 1);
    }
  }, [theme]);

  const _renderContent = () => {
    if (state.loading) return null;
    if (!state.tableData?.length) return <TRDefault type="empty" />;
    return (
      <div className={styles.mainInner}>
        <div className={styles.title}>{state.title}出清结果</div>
        <div className={styles.content}>
          <div className={styles.table}>
            <div className={styles.inhead}>
              <TjDimension
                value={state.order}
                options={orderOptions}
                onChange={(order) => setState({ order })}
                onPoly={() => fetch()}
              />
            </div>
            <div className={styles.inbody}>
              <TjTable {...pipeline.getProps()} useVirtual={false} />
            </div>
          </div>
          <div className={styles.space} />
          <div className={styles.chart}>
            <div className={styles.inhead}>
              <Space size={16}>
                {state.filterOptions.map((options, lv) => (
                  <Select
                    key={lv}
                    style={{ minWidth: 140 }}
                    value={state.filters[lv]}
                    options={options}
                    optionFilterProp="label"
                    onChange={(idx) => onChangeFilterItem(lv, idx)}
                    showSearch
                  />
                ))}
              </Space>
            </div>
            <div className={styles.inbody}>
              <TjChart option={state.chartOptions} />
            </div>
          </div>
        </div>
      </div>
    );
  };

  if (state.spinning) return <PageLoading />;
  if (state.error) return <TRDefault type="error" message={state.error} />;
  if (!state.power?.length) return <TRDefault type="lock" />;
  return (
    <Spin spinning={state.loading}>
      <div className={styles.container}>
        <div className={styles.head}>
          <HeadForm power={state.power} onChange={onChangeForm} />
          <div>
            <Button
              style={{ padding: 0 }}
              type="link"
              icon={<UploadOutlined />}
              onClick={_onExport}
            >
              导出
            </Button>
          </div>
        </div>
        <div className={styles.main}>
          <div className={styles.box}>{_renderContent()}</div>
        </div>
      </div>
    </Spin>
  );
};

export default connect(({ global }) => ({
  menuCode: global.configure.menuCode,
  buttonPermissions: global.configure.buttonPermissions,
}))(RollTradeClearingResults);
